let fn = undefined;

//↓代码执行到这里时,发现要赋的值是一个对象,So开辟一个堆内存空间,
// 然后开始挨个存储对象里的键值对
// 执行到fn:()=>fn()时
// 发现()=>fn()是一个函数,就又会开辟一个堆内存空间,用来存储函数字符串,存储完后会把这第二个开辟的堆内存的空间地址赋给fn(key)
// TODO 注意这里并不会解析函数体,意思是说我们这里的()=>{fn()},会直接将`{fn()}`函数体的内容存起来 而不会校验是否有fn这个函数 或则fn是不是个函数
// 最后把开辟的第一个堆内存的地址赋给paramObj
let paramObj = {
  fn:()=>fn()
};

function abc(paramObj){
  return () => paramObj.fn();
}

let x = abc(paramObj);

fn = () => console.log('fnxxxx');

x(); // 'fnxxxx'
/*
x函数执行,首先会开辟一个栈空间
然后通过abc返回的函数`() => paramObj.fn()`的地址 找到 `() => paramObj.fn()`对应的堆内存地址
将堆内存地址里的函数体拷贝到开辟出来的栈空间 字符串变为真正的js表达式，按照从上到下顺序在私有作用域中执行
`() => paramObj.fn()`函数开始执行
执行到`paramObj.fn()`这一行
会顺着作用域链找到 paramObj(这里是找到了abc闭包保存的参数paramObj,paramObj的地址)
调用paramObj.fn
开辟新的栈内存
通过key fn存的`()=>fn()`函数地址 找到 对应的堆内存
从堆内存拷贝 `()=>fn()` 函数字符串到新的栈内存 字符串变为真正的js表达式，按照从上到下顺序在私有作用域中执行

而此时fn已经变成了 () => console.log('fnxxxx');

TODO 综上 这是利用了 函数创建时不会检测函数内语法只是作为字符串拷贝到堆内存 的特性 以实现类似于 引用赋值的效果
*/
